package com.mock.water.config.shiro;

import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;

import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Author ifredomvip@gmail.com
 * @Date 2023/3/25 14:35
 */
@Configuration
public class ShiroConfig {

    @Bean
    public DefaultWebSecurityManager securityManager(UserRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

        securityManager.setRealm(userRealm);
        // securityManager.setRealms(Arrays.asList(userRealm(),tokenRealm()));

        // 设置Session管理器，配置shiro中Session的持续时间
//        securityManager.setSessionManager(getDefaultWebSessionManager());

        // 关闭shiro自带的session [文档](http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29)
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
        // 不需要将 Shiro Session 中的东西存到任何地方（包括 Http Session 中）
        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
        securityManager.setSubjectDAO(subjectDAO);

        return securityManager;
    }


    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        shiroFilterFactoryBean.setSuccessUrl("/index");
        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");

        // 自定义过滤器
        Map<String, Filter> filters = new LinkedHashMap<>();
        filters.put("myAuthFilter", new MyAuthFilter());
        shiroFilterFactoryBean.setFilters(filters);

        // 定义过滤链
        ShiroFilterChainDefinition shiroFilterChainDefinition = shiroFilterChainDefinition();
        shiroFilterFactoryBean.setFilterChainDefinitionMap(shiroFilterChainDefinition.getFilterChainMap());

        return shiroFilterFactoryBean;
    }

    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
        // 登录，
        chainDefinition.addPathDefinition("/login", "anon");
        // 注册
        chainDefinition.addPathDefinition("/register", "anon");
        // 错误页面
        chainDefinition.addPathDefinition("/error", "anon");
        // 登出，shiro 自动清除 session
        chainDefinition.addPathDefinition("/logout", "logout");

        // druid连接池的角色控制，只有拥有admin角色的admin用户可以访问，不理解可以先不管
        chainDefinition.addPathDefinition("/druid/**", "authc, roles[admin]");

        // 其余资源都交给 MyFilter 这个过滤器处理
        chainDefinition.addPathDefinition("/**", "myAuthFilter");

        return chainDefinition;
    }

    @Bean
    public UserRealm userRealm() {
        UserRealm realm = new UserRealm();

//        CredentialsMatcher matcher = new JwtCredentialsMatcher();
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("md5");
        matcher.setHashIterations(3);

        realm.setCredentialsMatcher(matcher);

//        //开启缓存管理
//        realm.setCacheManager(new EhCacheManager());
//        //开启全局缓存管理
//        realm.setCachingEnabled(true);
//        //开启认证和授权的缓存
//        realm.setAuthenticationCachingEnabled(true);
//        realm.setAuthorizationCachingEnabled(true);
//        //给缓存起个名字
//        realm.setAuthenticationCacheName("AuthenticationCache");
//        realm.setAuthorizationCacheName("AuthorizationCache");

        return realm;
    }

    /**
     * 设置session过期时间
     *
     * @return {@link DefaultWebSessionManager}
     */
    @Bean
    public DefaultWebSessionManager getDefaultWebSessionManager() {
        DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
        // 会话过期时间，单位：毫秒--->一分钟,用于测试
        defaultWebSessionManager.setGlobalSessionTimeout(1000 * 60);
        defaultWebSessionManager.setSessionValidationSchedulerEnabled(true);
        defaultWebSessionManager.setSessionIdCookieEnabled(true);
        return defaultWebSessionManager;
    }

}
